package com.zzy.util.activiti;

import com.zzy.model.Leave;
import com.zzy.service.LeaveService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.util.StringUtils;

import java.util.*;

/**流程发起*/
public class UtilFlow {

    //**流程业务类型*/
    public static final String TYPE_LEAVE = "LEAVE";//请假流程的标示
    public static final String TYPE_CWSP = "CWSP";//请假流程的标示
    public static final String TYPE_HS = "HS";//请假流程的标示

    //**项目流程key*/
    public static final String KEY_LEAVE = "LEAVE_PRO";//请假流程 图的key
    public static final String KEY_CWSP = "CWSP_PRO";//财务审批流程 图的key
    public static final String KEY_HS = "HS_PRO";//会审测试流程图的key


    public static final String FLOW_END = "end";//流程结束--通过结束
    public static final String FLOW_REFUSE= "refuse";//流程结束--不通过结束



    /**
     * 从classpath的资源中加载流程定义Id，一次只能加载一个文件
     * @return pdId 流程定义ID name 流程定义名
     */
    @Deprecated
    public static Map<String,Object> getProcessDefinitionInfo(RepositoryServiceImpl repositoryService){
        if(repositoryService == null){return null;}
        Map<String,Object> result = new HashMap<String,Object>();
        Deployment deployment = repositoryService//与流程定义和部署对象相关的Service
                .createDeployment()//创建一个部署对象
                .name("流程定义")//添加部署名称
                .addClasspathResource("/MyProcess.bpmn")
                //.addClasspathResource("/HelloWorld.png")
                .deploy();//完成部署
        ProcessDefinitionQuery pdQuery = repositoryService.createProcessDefinitionQuery();
        ProcessDefinition pd = pdQuery.deploymentId(deployment.getId()).singleResult();
        result.put("pdId", pd.getId());
        result.put("name", pd.getName());

        return result;
    }

    /**
     * 根据流程Key,查询已经部署的流程定义
     * @param processModelKey
     * @param repositoryService
     * @return
     */
    public static Map<String,Object> getProcessDefinitionInfo(String processModelKey,RepositoryServiceImpl repositoryService ){
        if(repositoryService == null){return null;}
        Map<String,Object> result = new HashMap<String,Object>();

        ProcessDefinition  pd =repositoryService.createProcessDefinitionQuery().processDefinitionKey(processModelKey).latestVersion().singleResult();

        result.put("pdId", pd.getId());
        result.put("name", pd.getName());

        return result;
    }


    public static Map<String,Object> getProcessDefinitionInfo(RepositoryServiceImpl repositoryService, RuntimeService runtimeService , String processKey){
        //判断流程key是否为空
        if(!StringUtils.hasText(processKey)){return null;}

        ProcessInstance processIstance=runtimeService.startProcessInstanceByKey(processKey);

        Map<String,Object> result = new HashMap<String,Object>();

        ProcessDefinitionQuery pdQuery = repositoryService.createProcessDefinitionQuery();
        ProcessDefinition  pd = pdQuery.deploymentId(processIstance.getId()).singleResult();
        processIstance.getId();
        result.put("pdId", pd.getId());
        result.put("name", pd.getName());
        return result;
    }

    //启动流程
    public static String createProcessInstance(Map<String,Object> map,String pdId,  RuntimeService runtimeService){
        if(runtimeService == null){return null;}
        ProcessInstance pi = runtimeService.startProcessInstanceById(pdId, map);
        return pi.getId();
    }

    /** 获取流程的环节信息*/
    public static List<Map<String,Object>> getCandidateUserExpressions(String processDefinitionId
            , RepositoryServiceImpl repositoryService) {
        List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
        if(repositoryService == null) {return null;}
        //获取流程定义的所有环节
        ProcessDefinitionImpl processDefinitionImpl =  (ProcessDefinitionImpl)repositoryService
                .getDeployedProcessDefinition(processDefinitionId);
        List<ActivityImpl>  activitiList = processDefinitionImpl.getActivities();
        for(ActivityImpl act : activitiList){ //流程节点信息
            Map<String,Object> prop = act.getProperties();//节点属性
            String type = prop.get("type").toString();//节点类型
            if("userTask".equals(type)){
                Map<String,Object> map = new HashMap<String, Object>();
                TaskDefinition td = (TaskDefinition) prop.get("taskDefinition");//任务定义类
                List<String> candidates = getLingCandidates(td);//候选人列表
                map.put("activityId", act.getId());//节点id
                map.put("activityName", prop.get("name"));//节点属性
                map.put("candidates", candidates);//候选人用户表达式
                result.add(map);
            }
        }
        return result;
    }

    /**获取候选人列表*/
    public static List<String> getLingCandidates(TaskDefinition t){
        List<String> candidates = new ArrayList<String>();//候选人列表
        @SuppressWarnings("rawtypes")
        Set set = new HashSet();
        if(t.getCandidateUserIdExpressions().size() > 0){
            set = t.getCandidateUserIdExpressions();
        } else if(t.getCandidateGroupIdExpressions().size() > 0) {
            set = t.getCandidateGroupIdExpressions();
        }
        if(set.size() > 0){
            Object[] objs = set.toArray();
            for(Object obj : objs){
                if(obj != null){
                    String tmp = obj.toString();//格式为${xxx}
                    if(tmp.length() > 3){
                        candidates.add(tmp.substring(2, tmp.length()-1));
                    }
                }
            }
        } else if(t.getAssigneeExpression() != null){
            Object obj = t.getAssigneeExpression();
            if(obj != null){
                String tmp = obj.toString();
                if(tmp.length() > 3){
                    candidates.add(tmp.substring(2, tmp.length()-1));
                }
            }
        }
        return candidates;
    }

    /**
     * 查询用户的待办任务
     * @param userId
     * @param processInstanceId 流程实例ID
     * @return  任务列表
     */
    public static List<Task> queryTaskByProcessInstance(String userId, String processInstanceId, TaskService taskService) {
        if(taskService == null) return null;
        List<Task> tasks = null;
        if("".equals(processInstanceId)){
            tasks = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(userId)
                    .orderByTaskCreateTime().asc()
                    .list();
        } else {
            tasks = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(userId)
                    .processInstanceId(processInstanceId)
                    .orderByTaskCreateTime().asc()
                    .list();
        }
        return tasks;
    }

    /**
     * 查询用户的待办任务
     * @param userId
     * @param businessType 业务模块
     * @return  任务列表
     */
    public static List<Task> queryTask(String userId,String businessType,TaskService taskService) {
        if(taskService == null) return null;
        List<Task> tasks = null;
        if("".equals(businessType)){
            tasks = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(userId)
                    .orderByTaskCreateTime().asc()
                    .list();
        } else {
            tasks = taskService.createTaskQuery()
                    .taskCandidateOrAssigned(userId)
                    .processVariableValueEqualsIgnoreCase("businessType", businessType)
                    .orderByTaskCreateTime().asc()
                    .list();
        }
        return tasks;
    }




    public static void startFlow(Class cla,Object service){
        Object objcla;
        try {
            objcla = cla.newInstance();
            if(objcla instanceof Leave){//请假流程
                LeaveService leaveService = (LeaveService)service;
                //leaveService.startFlow();
            }else if(1==2){

            }



        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }



}
